﻿// (c) Copyright 2013 Mike Riedel.
// This source is subject to the Microsoft Public License (Ms-PL).
// All other rights reserved.

using System;
using FreshMeat.ErrorHandlingBlock;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace ErrorHandlingBlock.Tests
{
   [TestClass]
   public class BackoffRetryPlanTest
   {
      [TestMethod]
      public void BackoffLifecycle()
      {
         const int exp = 2;
         var plan = new BackoffRetryPlan(6, TimeSpan.FromTicks(1), TimeSpan.FromTicks(3), TimeSpan.FromTicks(20), exp);

         var attempt = 1;

         Assert.IsTrue(plan.ShouldRetry(attempt), "Should retry because it's been attempted 1 time and max is 6.");
         Assert.AreEqual(1, plan.GetTimeUntilNextAttempt(attempt).Ticks, "Should use first wait because it's been attempted 1 time and max is 6.");

         attempt = 2;

         Assert.IsTrue(plan.ShouldRetry(attempt), "Should retry because it's been attempted 2 times and max is 6.");
         Assert.AreEqual(3, plan.GetTimeUntilNextAttempt(attempt).Ticks, "Should use subsequent wait because it's been attempted 2 times and max is 6.");

         attempt = 3;

         Assert.IsTrue(plan.ShouldRetry(attempt), "Should retry because it's been attempted 3 times and max is 6.");
         Assert.AreEqual(6, plan.GetTimeUntilNextAttempt(attempt).Ticks, "Should use 3*2 because it's been attempted 3 times and max is 6.");

         attempt = 4;

         Assert.IsTrue(plan.ShouldRetry(attempt), "Should retry because it's been attempted 4 times and max is 6.");
         Assert.AreEqual(12, plan.GetTimeUntilNextAttempt(attempt).Ticks, "Should use 3*2*2 because it's been attempted 4 times and max is 6.");

         attempt = 5;

         Assert.IsTrue(plan.ShouldRetry(attempt), "Should retry because it's been attempted 4 times and max is 6.");
         Assert.AreEqual(20, plan.GetTimeUntilNextAttempt(attempt).Ticks, "Should use maxwait of 20 because it's been attempted 5 times and max is 6.");

         attempt = 6;

         Assert.IsFalse(plan.ShouldRetry(attempt), "Should NOT retry because it's been attempted 6 times and max is 6.");

         attempt = 7;

         Assert.IsFalse(plan.ShouldRetry(attempt), "Should NOT retry because it's been attempted 7 times and max is 6.");
      }
   }
}